package cn.turboinfo.dongying.api.provider.common.service.impl.dictconfig;

import cn.turboinfo.dongying.api.domain.common.service.dictconfig.DictConfigItemService;
import cn.turboinfo.dongying.api.entity.common.exception.dictconfig.DictConfigItemException;
import cn.turboinfo.dongying.api.entity.common.pojo.dictconfig.DictConfigItem;
import cn.turboinfo.dongying.api.entity.common.pojo.dictconfig.DictConfigItemCreator;
import cn.turboinfo.dongying.api.entity.common.pojo.dictconfig.DictConfigItemUpdater;
import cn.turboinfo.dongying.api.provider.common.repository.database.dictconfig.DictConfigItemDAO;
import cn.turboinfo.dongying.api.provider.common.repository.database.dictconfig.DictConfigItemPO;
import lombok.RequiredArgsConstructor;
import net.sunshow.toolkit.core.qbean.api.request.QPage;
import net.sunshow.toolkit.core.qbean.api.request.QRequest;
import net.sunshow.toolkit.core.qbean.api.response.QResponse;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanCreatorHelper;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanUpdaterHelper;
import net.sunshow.toolkit.core.qbean.helper.service.impl.AbstractQServiceImpl;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

@RequiredArgsConstructor
@Service
public class DictConfigItemServiceImpl extends AbstractQServiceImpl<DictConfigItem> implements DictConfigItemService {
    private final DictConfigItemDAO dictConfigItemDAO;

    @Override
    public Optional<DictConfigItem> getById(Long id) {
        return dictConfigItemDAO.findById(id).map(this::convertQBean);
    }

    @Override
    public DictConfigItem getByIdEnsure(Long id) {
        return getById(id).orElseThrow(this.getExceptionSupplier("未找到数据, id=" + id, null));
    }

    @Override
    public List<DictConfigItem> findByIdCollection(Collection<Long> idCollection) {
        return convertStreamQBeanToList(dictConfigItemDAO.findByIdInOrderByIdDesc(idCollection).stream());
    }

    @Override
    @Transactional
    public DictConfigItem save(DictConfigItemCreator creator) throws DictConfigItemException {
        DictConfigItemPO dictConfigItemPO = new DictConfigItemPO();

        QBeanCreatorHelper.copyCreatorField(dictConfigItemPO, creator);

        return convertQBean(dictConfigItemDAO.save(dictConfigItemPO));
    }

    @Override
    @Transactional
    public DictConfigItem update(DictConfigItemUpdater updater) throws DictConfigItemException {
        DictConfigItemPO dictConfigItemPO = getEntityWithNullCheckForUpdate(updater.getUpdateId(), dictConfigItemDAO);

        QBeanUpdaterHelper.copyUpdaterField(dictConfigItemPO, updater);

        return convertQBean(dictConfigItemPO);
    }

    @Override
    public QResponse<DictConfigItem> searchList(QRequest request, QPage requestPage) {
        return convertQResponse(findAllInternal(request, requestPage));
    }

    private Page<DictConfigItemPO> findAllInternal(QRequest request, QPage requestPage) {
        return dictConfigItemDAO.findAll(convertSpecification(request), convertPageable(requestPage));
    }

    @Override
    @Transactional
    public void deleteById(Long id) throws DictConfigItemException {
        DictConfigItemPO dictConfigItemPO = getEntityWithNullCheckForUpdate(id, dictConfigItemDAO);
        dictConfigItemDAO.delete(dictConfigItemPO);
    }

    @Override
    public Optional<DictConfigItem> getDictConfigItem(String dictConfigKey, String itemValue) {
        return dictConfigItemDAO.findByDictConfigKeyAndItemValue(dictConfigKey, itemValue).map(this::convertQBean);
    }

    @Override
    public DictConfigItem getDictConfigItemEnsure(String dictConfigKey, String itemValue) {
        return getDictConfigItem(dictConfigKey, itemValue).orElseThrow(this.getExceptionSupplier(String.format("未找到数据, dictConfigKey=%s, itemValue=%s", dictConfigKey, itemValue), null));
    }

    @Override
    public List<DictConfigItem> findAllDictConfigItem(String dictConfigKey) {
        return convertStreamQBeanToList(dictConfigItemDAO.findByDictConfigKeyOrderByItemOrderAsc(dictConfigKey).stream());
    }

    @Override
    @Transactional
    public void updateDictConfigKey(Long dictConfigId, String dictConfigKey) {
        dictConfigItemDAO.findByDictConfigIdOrderByItemOrderAsc(dictConfigId)
                .forEach(it -> it.setDictConfigKey(dictConfigKey));
    }

    @Override
    protected Supplier<? extends RuntimeException> getExceptionSupplier(String message,
                                                                        Throwable cause) {
        return () -> new DictConfigItemException(message, cause);
    }
}
